home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d21 / dvglue10.arc / TVJNEW.C < prev    next >
C/C++ Source or Header  |  1988-08-13  |  6KB  |  185 lines

  1. /*=======================================================*/
  2. /*  TVJNEW.C                                             */
  3. /*                                                       */
  4. /*  (c) Copyright 1988 Ralf Brown  All Rights Reserved   */
  5. /*  May be freely copied for noncommercial use, so long  */
  6. /*  as this copyright notice remains intact, and any     */
  7. /*  changes are marked in the comment blocks preceding   */
  8. /*  functions.                                           */
  9. /*=======================================================*/
  10.  
  11. #pragma inline
  12.  
  13. #include <string.h>
  14. #include <stdarg.h>
  15. #include "tvapi.h"
  16.  
  17. #define STACKSIZE 256
  18.  
  19. static int _TV_newapp_mutex_ = 0 ;
  20.  
  21. /*======================================================*/
  22.  
  23. struct EXEC_block {
  24.        int env ;  /* segment of environment */
  25.        char far *cmdline ;
  26.        char far *fcb_1 ;
  27.        char far *fcb_2 ;
  28.     } ;
  29.  
  30. static char far *new_program ;
  31. static struct EXEC_block far *exec_block ;
  32.  
  33. /*======================================================*/
  34. /* launch_app  fork to here, and then EXEC the program  */
  35. /*   Ralf Brown 5/10/88                                 */
  36. /*   Ralf Brown 6/6/88  added own spawn routine         */
  37. /*======================================================*/
  38.  
  39. static void launch_app(int parent)
  40. {
  41.    struct EXEC_block far *exec_blk = exec_block ;
  42.    char far *program = new_program ;
  43.  
  44.    (void) parent ;  /* satisfy TurboC's warnings about unused parameters */
  45.    /* we've now got copies of the static variables, so we can unblock */
  46.    _TV_newapp_mutex_ = 0 ;
  47.  
  48.    /* EXEC the program and get its exit code */
  49.    asm push ds
  50.    asm mov bx,exec_block
  51.    asm mov es,exec_block+2
  52.    asm mov dx,new_program
  53.    asm mov ds,new_program+2
  54.    asm mov ax,4b00h
  55.    asm int 21h
  56.    asm pop ds
  57.    asm jnc no_error
  58.    /* waiting for exit code with INT 21h/AH=4Dh hangs process */
  59. no_error:
  60.  
  61.    free((char *) program) ;
  62.    free((char *) exec_blk->fcb_1) ;
  63.    free((char *) exec_blk->cmdline) ;
  64.    free((char *) exec_blk) ;
  65. }
  66.  
  67. /*======================================================*/
  68. /* TVapp_new  create new application in current process */
  69. /*   Ralf Brown 5/10/88                                 */
  70. /*   Ralf Brown 8/6/88 made it use vararg list, and     */
  71. /*              renamed to TVspawnve.  TVapp_new now    */
  72. /*              calls this function                     */
  73. /*======================================================*/
  74.  
  75. OBJECT pascal TVspawnve(OBJECT win,int row,int col,int rows,int cols,
  76.                         int switch_menu,char *program,va_list args,int env)
  77. {
  78.    OBJECT new_app = NIL ;
  79.    char *arg ;
  80.    int cmd_len = 0 ;
  81.    char *cmd_line, *cmd, *rest ;
  82.    struct fcb *fcb1, *fcb2 ;
  83.  
  84.    /* allocate space for the commandline and FCBs */
  85.    if ((cmd_line = malloc(128)) == NULL)
  86.       goto error2 ;
  87.    if ((fcb1 = malloc(2*sizeof(struct fcb))) == NULL)
  88.       {
  89.       free(cmd_line) ;
  90.       goto error2 ;
  91.       }
  92.    cmd = cmd_line+1 ;
  93.    fcb2 = fcb1+1 ;
  94.    /* we'll be overwriting static vars, so can only have one copy here at a time */
  95.  
  96. busy_wait:
  97.    asm mov ax,1
  98.    asm lock xchg ax,_TV_newapp_mutex_
  99.    asm or ax,ax
  100.    asm jz wait_done
  101.    TVpause() ;
  102.    asm jmp busy_wait
  103. wait_done:
  104.  
  105.    if ((new_program = (char far *)malloc(strlen(program)+1)) != NULL)
  106.       strcpy((char *)new_program, program) ;
  107.    else
  108.       {
  109.       free(cmd_line) ;
  110.       free(fcb1) ;
  111.       goto error ;
  112.       }
  113.    if ((exec_block = (struct EXEC_block far *)malloc(sizeof(struct EXEC_block))) != NULL)
  114.       {
  115.       exec_block->env = env ;
  116.       exec_block->cmdline = (char far *)cmd_line ;
  117.       exec_block->fcb_1 = (char far *)fcb1 ;
  118.       exec_block->fcb_2 = (char far *)fcb2 ;
  119.       }
  120.    else
  121.       {
  122.       free(cmd_line) ;
  123.       free(fcb1) ;
  124.       free((char *)new_program) ;
  125.       goto error ;
  126.       }
  127.    /* then concatenate the args to form the commandline */
  128.    (void) va_arg( args, char * ) ;  /* skip argv[0] */
  129.    while ((arg = va_arg(args, char *)) != NULL)
  130.       {
  131.       while (*arg && cmd_len < 126)
  132.          {
  133.          *cmd++ = *arg++ ;
  134.          cmd_len++ ;
  135.          }
  136.       if (cmd_len >= 126)
  137.          {
  138.          cmd_len = 126 ;
  139.          break ;
  140.          }
  141.       else
  142.          {
  143.          *cmd++ = ' ' ;  /* separate args by blanks */
  144.          cmd_len++ ;
  145.          }
  146.       }
  147.    cmd_line[0] = cmd_len ;
  148.    cmd_line[cmd_len+1] = '\r' ;
  149.    va_end( args ) ;
  150.    /* now set up the FCBs */
  151.    rest = parsfnm( cmd_line+1, (struct fcb *)fcb1, 1 ) ;  /* 1=ignore leading separators */
  152.    if (rest)  /* was first parse successful? */
  153.       rest = parsfnm( rest, (struct fcb *)fcb2, 1 ) ;
  154.    /* and launch the program */
  155.    new_app = TVtask_new(win,NULL,row,col,rows,cols,NULL,STACKSIZE,launch_app,switch_menu) ;
  156.    if (new_app)
  157.       return new_app ;
  158. error:
  159.    _TV_newapp_mutex_ = 0 ;  /* release exclusion since we never launched the program */
  160. error2:
  161.    return new_app ;
  162. }
  163.  
  164. /*======================================================*/
  165. /* TVapp_new  create new application in current process */
  166. /*   Ralf Brown 5/10/88                                 */
  167. /*======================================================*/
  168.  
  169. OBJECT cdecl TVapp_new(OBJECT win,int row,int col,int rows,int cols,
  170.                        int switch_menu,char *program, ...)
  171. {
  172.    return TVspawnve(win,row,col,rows,cols,switch_menu,program,_va_ptr,0) ;
  173. }
  174.  
  175. OBJECT cdecl TVspawnle(OBJECT win,int row,int col,int rows,int cols,
  176.                        int switch_menu,char **env,char *program, ...)
  177. {
  178.    int env_seg ;
  179.  
  180. env_seg = 0 ; /* until I figure out how to set it */
  181.    return TVspawnve(win,row,col,rows,cols,switch_menu,program,_va_ptr,env_seg) ;
  182. }
  183.  
  184. /* End of TVJNEW.C */
  185.